#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>

#if defined LINK_HARDWARE 	//TuchGFX仿真与实际硬件操作隔离
	//头文件包含
	extern "C"
	{
		#include "user_app.h"
	}
	//底层数据
	extern volatile SHT20_TemRH_Val gTemRH_Val;
	extern RTC_DateTypeDef gSystemDate;  //获取日期结构体
	extern RTC_TimeTypeDef gSystemTime;   //获取时间结构体
	extern gTask_BitDef gTaskStateBit;  //任务执行过程中使用到的标志位
	extern gTask_MarkEN gTaskEnMark;  //系统任务使能标识
	extern volatile StruAP3216C_Val gAP3216C_Val;	//AP3216数据结构
	extern volatile uint8_t gLastTimeSeconds;	//上一次的时间
	extern volatile float pitch,roll,yaw; //欧拉角
	extern unsigned long gSportStep;	//运动步数
	extern wifiRSSI ao_wifiRSSI;
	
	extern uint8_t gFiveKeyFunc;	//定义的五向按键值功能	
	
	extern volatile uint16_t gCurrentVal;	//资源扩展板电流，通道IN8   
	extern volatile uint16_t gVoltageVal;	//资源扩展板电压，通道IN9  
	extern volatile uint16_t gChipTempVal;//内部参考电压，通道IN12  
	extern volatile uint16_t gVrefVal;		//内部参考电压，通道IN13   	
	extern volatile uint16_t gVbatVal;		//RTC电池电压，通道IN14  

#if defined MAX30102_ENABLE
	extern int32_t n_heart_rate;   //heart rate value=n_heart_rate/4,采样率100sps,max30102设置4点求平均
	extern int32_t n_sp02; //SPO2 value
	extern int8_t ch_spo2_valid;   //indicator to show if the SP02 calculation is valid
	extern int8_t  ch_hr_valid;    //indicator to show if the heart rate calculation is valid
#endif
	extern uint8_t gWiFiInfo[40];	//用于通知View界面的Text文本显示
	//
	volatile uint8_t gSwitchSpace = 0x00;	//页面切换的时间间隙
	static int32_t gHeartRate = 0;  //表盘页面的心率数据
#else //Designer仿真
	#include <ctime>
	#ifndef _MSC_VER
	#include <sys/time.h>
	#endif /* _MSC_VER*/
	//
	volatile uint8_t gBacklightVal = 50;	//背光值，默认50%
#endif
/**********************************TouchGFX与底层间的访问**********************************/
Model::Model() : modelListener(0)
{

}
//
void Model::tick()
{
	static uint8_t tickCount = 0;	//减少数据上传的次数，优化界面刷新
	tickCount++;	

#if defined LINK_HARDWARE
	//
	if(gSwitchSpace != 0) gSwitchSpace--;	
	/********************************硬件页面切换*********************************/
	//表盘页面
	if(gTaskEnMark.UPDATE_DIAL_EN && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->DialPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//应用页面
	if(gTaskEnMark.UPDATE_APPPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))
	{
		modelListener->AppPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//六轴页面
	if(gTaskEnMark.UPDATE_SIX_AXIS_EN && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))
	{
		modelListener->SixAxisPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//无线页面
	if(gTaskEnMark.UPDATE_WIFIPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->WiFiPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//设置页面
	if(gTaskEnMark.UPDATE_SETTINGPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->SettingPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//控制页面
	if(gTaskEnMark.UPDATE_MOTORPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->MotorPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//信息页面，温度、湿度与光强度
	if(gTaskEnMark.UPDATE_INFOPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->InfoPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//健康页面
	if(gTaskEnMark.UPDATE_HEALTHPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->HealthPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//Chip页面
	if(gTaskEnMark.UPDATE_CHIPPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->ChipPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//Battery页面
	if(gTaskEnMark.UPDATE_BATTERYPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->BatteryPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//Sport页面退出
	if(gTaskEnMark.UPDATE_SPORTPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->SportPageExit(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//Alipay页面退出
	if(gTaskEnMark.UPDATE_ALIPAYPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->AlipayPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//Sport页面进入
	if(!HAL_GPIO_ReadPin(USER_KEY_GPIO_Port,USER_KEY_Pin))	
	{
		modelListener->SportPageEnter(3);	
	}
	/********************************更新各类信息*********************************/
	//更新时间信息,为使表盘页面滑动操作正常，在屏幕被点按时不更新数据
	if(gTaskEnMark.UPDATE_DIAL_EN && (gSystemTime.Seconds != gLastTimeSeconds)&&(gTaskStateBit.TouchPress == 0))	//每秒同步一次界面时间
	{
		modelListener->updateDate(gSystemDate.Year,gSystemDate.Month,gSystemDate.Date,gSystemDate.WeekDay);
		modelListener->updateTime(gSystemTime.Hours, gSystemTime.Minutes, gSystemTime.Seconds);
		//更新新值
		gLastTimeSeconds = gSystemTime.Seconds;	
		//更新温度/步数/心率
		modelListener->updateTempStepHeart(gTemRH_Val.Tem,gSportStep,gHeartRate);
	}
	//健康监测信息上传
	if(gTaskEnMark.UPDATE_HEALTHPAGE && (gTaskStateBit.TouchPress == 0))	
	{
#if defined MAX30102_ENABLE
		//send samples and calculation result to terminal program through UART
		if(ch_hr_valid || ch_spo2_valid)
		{
			modelListener->updateHeartRateInfo(n_heart_rate/4, n_sp02);
			gHeartRate = n_heart_rate/4;  //保存心率数据值表盘页面
		}
		//
		if(gTaskStateBit.Max30102)	//单次测量完成，清除标志
		{
			ch_hr_valid =0;
			ch_spo2_valid=0;
			gTaskStateBit.Max30102 = 0;
		}
#endif
	}
	//更新欧拉角
	if(gTaskEnMark.UPDATE_SIX_AXIS_EN)	//六轴界面活动时上传
	{
		modelListener->updateSixAxis(pitch, roll, yaw);
	}
	//获取WiFi模组的RSSI值
	if((gTaskEnMark.UPDATE_WIFI_RSSI_EN))	//只有在系统主页时，才进行WiFi的RSSI数据读取
	{
		modelListener->updateWiFiRSSI(gWiFiInfo, ao_wifiRSSI.gRSSI);
	}
	//更新温湿度信息
	if(gTaskEnMark.UPDATE_INFOPAGE)	//INFO面活动时上传
	{
		modelListener->updateInfo(gTemRH_Val.Hum, gTemRH_Val.Tem, gAP3216C_Val.ALS);
	}
	//更新芯片参数
	if(gTaskEnMark.UPDATE_CHIPPAGE && (!(tickCount % 5)))
	{
		modelListener->updateChipInfor(gChipTempVal, gVrefVal, gVbatVal);	//更新芯片温度、参考电压、Vbat
	}	
	//更新电压与电流
	if(gTaskEnMark.UPDATE_BATTERYPAGE)
	{
		modelListener->updateBatteryPageInfo(gCurrentVal, gVoltageVal);	//更新电压与电流
	}	
#else //Designer仿真
		timeval timenow;
		gettimeofday(&timenow, NULL);
		//仿真更新时间
		modelListener->updateTime((timenow.tv_sec / 60 / 60) % 24,(timenow.tv_sec / 60) % 60,timenow.tv_sec % 60);
#endif	
}
//风扇操作
void Model::turnFanStatus(bool enable)
{
#if defined LINK_HARDWARE
		if(enable == true)
			HAL_GPIO_WritePin(EXT_FAN_GPIO_Port,EXT_FAN_Pin,GPIO_PIN_SET);	//风扇状态的设置
		else 
			HAL_GPIO_WritePin(EXT_FAN_GPIO_Port,EXT_FAN_Pin,GPIO_PIN_RESET);	
#endif
}
//振动电机操作
void Model::setMotorStatus(bool enable)
{
#if defined LINK_HARDWARE
		if(enable == true)
			HAL_GPIO_WritePin(EXT_MOTOR_GPIO_Port,EXT_MOTOR_Pin,GPIO_PIN_SET);	//振动电机状态的设置
		else 
			HAL_GPIO_WritePin(EXT_MOTOR_GPIO_Port,EXT_MOTOR_Pin,GPIO_PIN_RESET);	
#endif
}
//排水操作
void Model::drainWaterStatus(bool enable)
{
#if defined LINK_HARDWARE
		if(enable == true)
			HAL_GPIO_WritePin(EXT_MOTOR_GPIO_Port,EXT_MOTOR_Pin,GPIO_PIN_SET);	//振动电机设置
		else 
			HAL_GPIO_WritePin(EXT_MOTOR_GPIO_Port,EXT_MOTOR_Pin,GPIO_PIN_RESET);	
#endif
}
//蜂鸣器操作
void Model::setBuzzerStatus(bool enable)
{
#if defined LINK_HARDWARE
		if(enable == true)
			HAL_GPIO_WritePin(RUN_BEEP_GPIO_Port,RUN_BEEP_Pin,GPIO_PIN_SET);	//蜂鸣器状态的设置
		else 
			HAL_GPIO_WritePin(RUN_BEEP_GPIO_Port,RUN_BEEP_Pin,GPIO_PIN_RESET);	
#endif
}
/*********************gTaskEnMark赋值*************************/
//DialView的任务的状态
void Model::DialPageViewTask(bool enable)
{
	#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_DIAL_EN = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_DIAL_EN = 0;	//任务清除
#endif
}
//ApplicationPageView的任务的状态
void Model::ApplicationPageViewTask(bool enable)
{
	#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_APPPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_APPPAGE = 0;	//任务清除
#endif
}
//SixAxisPageView的任务的状态
void Model::SixAxisPageViewTask(bool enable)
{
#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_SIX_AXIS_EN = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_SIX_AXIS_EN = 0;	//任务清除
#endif
}
//InfoPageView任务使能
void Model::InfoPageViewTask(bool newStatus)
{
#if defined LINK_HARDWARE
	if(newStatus == true)	
		gTaskEnMark.UPDATE_INFOPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_INFOPAGE = 0;	//任务清除
#endif
}
//ChipPageViewTask的任务的状态
void Model::ChipPageViewTask(bool enable)
{
	#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_CHIPPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_CHIPPAGE = 0;	//任务清除
#endif
}
//设置健康监测任务
void Model::HealthPageViewTask(bool newStatus)
{
	#if defined LINK_HARDWARE
	if(newStatus == true)	
		gTaskEnMark.UPDATE_HEALTHPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_HEALTHPAGE = 0;	//任务清除
#endif
}
//WiFi连接的任务状态
void Model::WiFiLinkTask(bool enable)
{
#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_WIFI_RSSI_EN = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_WIFI_RSSI_EN = 0;	//任务清除
#endif
}
//WiFi界面的任务状态
void Model::WiFiPageViewTask(bool enable)
{
#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_WIFIPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_WIFIPAGE = 0;	//任务清除
#endif
}
//Setting界面的任务状态
void Model::SettingPageViewTask(bool enable)
{
#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_SETTINGPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_SETTINGPAGE = 0;	//任务清除
#endif
}
//Motor界面的任务状态
void Model::MotorPageViewTask(bool enable)
{
#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_MOTORPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_MOTORPAGE = 0;	//任务清除
#endif
}
//Battery界面的任务状态
void Model::BatteryPageViewTask(bool enable)
{
#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_BATTERYPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_BATTERYPAGE = 0;	//任务清除
#endif
}
//运动界面的任务状态
void Model::SportPageViewTask(bool enable)
{
#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_SPORTPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_SPORTPAGE = 0;	//任务清除
#endif
}
//Aliplay界面任务状态
void Model::AlipayPageViewTask(bool enable)
{
#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_ALIPAYPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_ALIPAYPAGE = 0;	//任务清除
#endif
}